package com.hmkj.admin.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hmkj.admin.utils.AdminSessionHelper;
import com.hmkj.common.baseMapper.GenericPo;
import com.hmkj.common.entity.ResultEntity;
import com.hmkj.common.entity.dtgrid.DtGrid;
import com.hmkj.core.constant.Enum;
import com.hmkj.core.exception.BussinessException;
import com.hmkj.core.exception.CaptchaException;
import com.hmkj.core.exception.DtGridException;
import com.hmkj.core.po.system.Admin;
import com.hmkj.core.po.user.User;
import com.hmkj.core.service.cache.RedisService;
import com.hmkj.core.service.cache.SessionService;
import com.hmkj.core.service.sms.SendMsgService;
import com.hmkj.core.service.user.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * json数据类controller 基础实现
 *
 * @param <PK> 对象主键类型
 * @param <PO> 对象
 */
@Slf4j
public class GenericController<PK, PO extends GenericPo<PK>> {

    protected final Logger logger = Logger.getLogger(getClass());

    /**
     * 操作成功
     *
     * @return
     */
    protected <T> ResultEntity<T> ok() {
        return result(null, "success", ResultEntity.SUCCESS);
    }

    /**
     * 操作成功
     *
     * @param po 返回数据
     * @return
     */
    protected <T> ResultEntity<T> ok(T po) {
        return result(po, "操作成功", ResultEntity.SUCCESS);
    }

    /**
     * 操作成功
     *
     * @param consumer 返回数据
     * @return
     */
    protected ResultEntity ok(Consumer<Map<String, Object>> consumer) {
        Map<String, Object> result = new HashMap<>();
        consumer.accept(result);
        return result(result, "success", ResultEntity.SUCCESS);
    }


    /**
     * 操作失败
     *
     * @return
     */
    protected <T> ResultEntity<T> fail(String msg) {
        return result(null, msg, ResultEntity.FAIL);
    }

    /**
     * 操作失败
     *
     * @return
     */
    protected <T> ResultEntity<T> fail() {
        return result(null, "操作失败", ResultEntity.FAIL);
    }

    protected String getSession(String key) {
        return AdminSessionHelper.getSession(key);
    }

    protected void setSession(String key, String val) {
        if (val != null) {
            AdminSessionHelper.setSession(key, val);
        }
    }

    @Resource
    protected RedisService redisService;
    @Resource
    protected SessionService sessionService;
    @Resource
    protected SendMsgService sendMsgService;
    @Resource
    protected UserService userService;


    /**
     * 返回消息记录
     *
     * @param resultData 返回实体(可空)
     * @param msg        返回消息
     * @param code       成功/错误
     * @return
     */
    protected <T> ResultEntity<T> result(T resultData, String msg, int code) {
        ResultEntity resultEntity = new ResultEntity();
        resultEntity.setData(resultData);
        resultEntity.setCode(code);
        resultEntity.setMessage(msg);
        return resultEntity;
    }

    /**
     * 后台列表异常全局处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler({DtGridException.class})
    public DtGrid dtGridException(DtGridException e) {
        log.error(e.toString(), e);
        DtGrid dtGrid = new DtGrid();
        dtGrid.setIsSuccess(false);
        return dtGrid;
    }

    /**
     * 全局异常处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler({Exception.class})
    public ResultEntity exception(Exception e) {
        e.printStackTrace();
        log.error(e.toString(), e);

        ResultEntity resultEntity = new ResultEntity();
        resultEntity.setCode(ResultEntity.FAIL);
        resultEntity.setMessage("参数错误");
        if (e instanceof BussinessException) {
            resultEntity.setMessage(e.getMessage());
        } else if (e instanceof IncorrectCredentialsException) {
            resultEntity.setMessage("登录密码错误");
        } else if (e instanceof ExcessiveAttemptsException) {
            resultEntity.setMessage("登录失败次数过多");
        } else if (e instanceof LockedAccountException) {
            resultEntity.setMessage("帐号已被锁定");
        } else if (e instanceof DisabledAccountException) {
            resultEntity.setMessage("帐号已被禁用");
        } else if (e instanceof ExpiredCredentialsException) {
            resultEntity.setMessage("帐号已过期");
        } else if (e instanceof UnknownAccountException) {
            resultEntity.setMessage("帐号不存在");
        } else if (e instanceof UnauthorizedException) {
            resultEntity.setMessage("您没有得到相应的授权");
        } else if (e instanceof DataIntegrityViolationException) {
            resultEntity.setMessage("参数命名重复");
        } else if (e instanceof CaptchaException) {
            resultEntity.setMessage("验证码输入错误");
        } else if (e instanceof AuthenticationException) {
            resultEntity.setMessage("用户名或密码错误");
        }
        return resultEntity;
    }

    protected String dataAuthority(String dtGridPager) throws Exception {
        Admin admin = AdminSessionHelper.getCurrAdmin();
        if (admin.getRoleId() == Enum.ONE_ROLE_ID || admin.getRoleId() == Enum.TWO_ROLE_ID || admin.getRoleId() == Enum.THREE_ROLE_ID || admin.getRoleId() == Enum.NEXT_SELLER_ROLE_ID) {
            User user = userService.selectByPrimaryKey(admin.getUserId());
            List<User> userList = userService.listPartnerByLevel(user.getCode(), 0);
            String userIds = "0";
            if (CollectionUtils.isNotEmpty(userList)) {
                userIds = userList.stream().map(param -> param.getId().toString()).collect(Collectors.joining(","));
            }
            ObjectMapper mapper = new ObjectMapper();
            DtGrid dtGrid1 = mapper.readValue(dtGridPager, DtGrid.class);
            Map<String, Object> dtGridFastQueryParameters = dtGrid1.getFastQueryParameters();
            dtGridFastQueryParameters.put("in_userId", userIds);
            dtGrid1.setFastQueryParameters(dtGridFastQueryParameters);
            dtGridPager = dtGrid1.toJsonString();
        }
        return dtGridPager;
    }

}
